package com.rem.chat.controller;

import com.rem.chat.common.config.AppConfig;
import com.rem.chat.common.constants.Constants;
import com.rem.chat.common.errcode.ControllerErrorCodeConstants;
import com.rem.chat.common.errcode.ErrorCode;
import com.rem.chat.common.exception.ControllerException;
import com.rem.chat.common.utils.JacksonUtil;
import com.rem.chat.common.utils.RedisUtil;
import com.rem.chat.common.utils.StringUtil;
import com.rem.chat.pojo.request.SendMessageRequest;
import com.rem.chat.pojo.response.CommonResult;
import com.rem.chat.pojo.response.SendMessageResponse;
import com.rem.chat.service.ChatService;
import com.rem.chat.service.dto.UserLoginDTO;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;

/**
 * @author: Themberfue
 * @date: 2025/6/21 15:55
 * @description:
 */
@RestController
@RequestMapping("/chat")
public class ChatController {
    private static final Logger log = LoggerFactory.getLogger(ChatController.class);
    @Resource
    RedisUtil redisUtil;

    @Resource(name = "chatServiceImpl")
    ChatService chatService;

    @Resource
    private AppConfig appConfig;

    @PostMapping("/sendMessage")
    public CommonResult<SendMessageResponse> sendMessage(@RequestBody @Validated SendMessageRequest param,
                                                         HttpServletRequest request) {
        log.info("sendMessage SendMessageRequest：{}", JacksonUtil.writeValueAsString(param));

        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        return CommonResult.success(
                chatService.sendMessage(param, user));
    }

    @PostMapping("/uploadFile")
    public CommonResult<Boolean> uploadFile(@NotNull Integer messageId,
                                            MultipartFile file, MultipartFile cover,
                                            HttpServletRequest request) throws IOException {
        log.info("uploadFile messageId：{}", messageId);

        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        return CommonResult.success(
                chatService.uploadFile(user.getUserId(), messageId, file, cover));
    }

    @PostMapping("/downloadFile")
    public CommonResult<Boolean> downloadFile(@NotNull String fileId,
                                              @NotNull Boolean showCover,
                                              HttpServletRequest request, HttpServletResponse response) {
        log.info("downloadFile fileId：{} showCover：{}", fileId, showCover);

        // Step 1. 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        // Step 2. 从服务器下载文件
        File file = chatService.downloadFile(user, fileId, showCover);

        try (FileInputStream in = new FileInputStream(file);
                OutputStream out = response.getOutputStream()) {
            // Step 3. 设置响应头
            response.setContentType("application/x-msdownload;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment");
            response.setContentLengthLong(file.length());

            // Step 4. 读取文件数据写到响应体
            byte[] data = new byte[1024];
            int len;
            while ((len = in.read(data)) != -1) {
                out.write(data, 0, len);
            }
            out.flush();
        } catch (IOException e) {
            log.error("文件下载失败");
            return CommonResult.fail(new ErrorCode(520, "文件下载失败"));
        }
        return CommonResult.success(true);
    }

    private UserLoginDTO getUserLoginDTO(HttpServletRequest request) {
        String token = request.getHeader("token");
        String user = redisUtil.get(Constants.REDIS_KEY_WS_TOKEN + token);
        log.info("user: {}", user);
        return JacksonUtil.readValue(user, UserLoginDTO.class);
    }
}
